package cn.fuxi2022.accounts.commonMessage.controller;

import cn.fuxi2022.accounts.commonMessage.service.WeChatCommonMessageService;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.mp.api.WxMpService;
import org.apache.commons.lang3.ObjectUtils;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


@Slf4j
@RestController
@RequestMapping("weChatCommonMessage")
public class WeChatCommonMessageController {

    @Autowired
    private WeChatCommonMessageService weChatCommonMessageService;

    @Autowired
    private WxMpService wxMpService;

    /**
     * 验证消息的确来自微信服务器
     * 开发者通过检验 signature 对请求进行校验（下面有校验方式）。
     * 若确认此次 GET 请求来自微信服务器，请原样返回 echostr 参数内容，则接入生效，成为开发者成功，否则接入失败。
     *
     * @param signature 微信加密签名，signature结合了开发者填写的 token 参数和请求中的 timestamp 参数、nonce参数。
     * @param timestamp 时间戳
     * @param nonce     随机数
     * @param echostr   随机字符串，确认此次 GET 请求来自微信服务器，原样返回 echostr 参数内容
     * @return 给服务器的响应
     */
    @GetMapping
    public String verifyToken(String signature, String timestamp, String nonce, String echostr) {
        if (ObjectUtils.isEmpty(signature) || ObjectUtils.isEmpty(timestamp) || ObjectUtils.isEmpty(nonce) || ObjectUtils.isEmpty(echostr)) {
            return "非法的微信服务器！！！";
        }

        // 1.获取必备参数
        log.info("signature: {} nonce: {} echostr: {} timestamp: {}", signature, nonce, echostr, timestamp);
        // 2.合法校验
        if (weChatCommonMessageService.verifyToken(signature, timestamp, nonce)) {
            log.info("token ok");
            // 3.确认此次 GET 请求来自微信服务器，请原样返回 echostr 参数内容
            return echostr;
        }
        return "非法的微信服务器！！！";
    }

    /**
     * 接收普通消息/接收事件推送 ---> 被动回复用户消息
     *
     * @param request 微信的请求
     */
    @PostMapping
    public String receiveMessage(HttpServletRequest request, HttpServletResponse response) throws UnsupportedEncodingException {
        request.setCharacterEncoding("UTF-8");
        response.setCharacterEncoding("UTF-8");
        Map<String, String> map;
        try {
            map = parseXml(request);
        } catch (Exception e) {
            return "success";
        }
        // 解决乱码问题
        return new String(weChatCommonMessageService.receiveMessage(map).getBytes(), "UTF-8");
    }

    /**
     * 解析微信推送的 XML 数据包
     *
     * @param request 微信的请求
     * @return 解析完成的map集合
     */
    private Map<String, String> parseXml(HttpServletRequest request) throws Exception {
        Map<String, String> map = new HashMap<String, String>();
        InputStream inputStream = request.getInputStream();
        SAXReader reader = new SAXReader();
        Document document = reader.read(inputStream);
        Element root = document.getRootElement();
        List<Element> elementList = root.elements();
        for (Element e : elementList) {
            map.put(e.getName(), e.getText());
        }
        inputStream.close();
        return map;
    }

}
